Shipping Go by Joel Holmes
Author:Joel Holmes [Joel Holmes]
Language: eng
Format: epub
Publisher: Manning Publications
Published: 2023-07-10T00:00:00+00:00
6.6 Fake
Finally, we will add one more set of unit tests for a client that calls an external API. Here, we come up against a different type of interface testing, this time with an API that we donât control. Like our other interfaces tests, we can establish a contract or definition of what this API should look like and use a fake to simulate it.
WARNING We donât have control over the other API, just our own, and if something were to change on the other API, we could end up with failures. This fake is simulating an external dependency, or a system outside our control, and therefore should be monitored and heavily logged in case failures such as outages occur. Advanced system patterns such as Circuit Breakers should be used, but they are outside the context of this book. I suggest Cloud Native Patterns (Manning, 2019) by Cornelia Davis.
A fake is an object, struct, or service with limited capabilities. So far, we have described stubs and mocks in the context of testing. We will use the term fake as a definition of an object that stands in for an external service. Fakes provide this last category of tools to help us verify the base units of our code before we start moving toward integrating with external integration.
Go provides the ability to create a test server to call against, which makes our testing easier. We will use a fake HTTP server to build our fake to test a client we create. Letâs set up our suite before we get into the details of the implementation. First, create the files using
touch translation/client.go touch translation/client_test.go
and then add the code in the following listing.
Listing 6.21 client_test.go
package translation_test import ( "encoding/json" "io" "io/ioutil" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" ) func TestHelloClientSuite(t *testing.T) { suite.Run(t, new(HelloClientSuite)) } type HelloClientSuite struct { suite.Suite mockServerService *MockService server *httptest.Server ⶠunderTest translation.HelloClient ⷠ} type MockService struct { mock.Mock } func (m *MockService) Translate(word, language string) (string, error) { ⸠args := m.Called(word, language) return args.String(0), args.Error(1) }
â¶ Use a test server to run against
â· We are going to be testing the interface defined here.
⸠Similar mock to the ones weâve seen before to help us inject values into the handler
To set up our client test, we will need to create a handler that captures the message to test what the client passes (see the following listing).
Listing 6.22 client_test.go
func (suite *HelloClientSuite) SetupSuite() { ⶠsuite.mockServerService = new(MockService) handler := func(w http.ResponseWriter, r *http.Request) { b, _ := ioutil.ReadAll(r.Body) defer r.Body.Close() var m map[string]interface{} _ = json.Unmarshal(b, &m) word := m["word"].(string) language := m["language"].(string) resp, err := suite.mockServerService.Translate(word, language) ⷠif err != nil { http.Error(w, "error", 500) } if resp == "" { http.Error(w, "missing", 404) } w.Header().Set("Content-Type", "application/json") _, _ = io.WriteString(w, resp) } mux := http.NewServeMux() mux.HandleFunc("/", handler) suite.server = httptest.NewServer(mux) ⸠} func (suite *HelloClientSuite) TearDownSuite() { suite.server.Close() ⹠}
â¶ SetupSuite is used because we donât want to create a new server for each test, just this group of tests.
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Deep Learning with Python by François Chollet(12593)
Hello! Python by Anthony Briggs(9928)
OCA Java SE 8 Programmer I Certification Guide by Mala Gupta(9804)
The Mikado Method by Ola Ellnestam Daniel Brolund(9787)
Dependency Injection in .NET by Mark Seemann(9348)
Algorithms of the Intelligent Web by Haralambos Marmanis;Dmitry Babenko(8310)
Test-Driven iOS Development with Swift 4 by Dominik Hauser(7773)
Grails in Action by Glen Smith Peter Ledbrook(7705)
The Well-Grounded Java Developer by Benjamin J. Evans Martijn Verburg(7568)
Becoming a Dynamics 365 Finance and Supply Chain Solution Architect by Brent Dawson(7192)
Microservices with Go by Alexander Shuiskov(6955)
Practical Design Patterns for Java Developers by Miroslav Wengner(6872)
Test Automation Engineering Handbook by Manikandan Sambamurthy(6816)
Secrets of the JavaScript Ninja by John Resig Bear Bibeault(6426)
Angular Projects - Third Edition by Aristeidis Bampakos(6235)
The Art of Crafting User Stories by The Art of Crafting User Stories(5750)
NetSuite for Consultants - Second Edition by Peter Ries(5676)
Demystifying Cryptography with OpenSSL 3.0 by Alexei Khlebnikov(5492)
Kotlin in Action by Dmitry Jemerov(5076)
